﻿using Nop.Admin.Models.Common;
using Nop.Admin.Models.Customers;
using Nop.Core;
using Nop.Core.Caching;
using Nop.Core.Domain.Customers;
using Nop.Services.Authentication;
using Nop.Services.Common;
using Nop.Services.Customers;
using Nop.Services.Directory;
using Nop.Services.Events;
using Nop.Services.ExportImport;
using Nop.Services.Helpers;
using Nop.Services.Localization;
using Nop.Services.Logging;
using Nop.Services.Security;
using Nop.Services.Stores;
using Nop.Web.Framework.Controllers;
using Nop.Web.Framework.Kendoui;
using Nop.Web.Framework.Mvc;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Web.Mvc;

namespace Nop.Admin.Controllers
{
	public partial class CustomerController : BaseAdminController
	{
		#region Fields

		private readonly ICustomerService _customerService;
		private readonly IAuthenticationService _authenticationService;
		private readonly IEventPublisher _eventPublisher;
		private readonly IGenericAttributeService _genericAttributeService;
		private readonly ICustomerRegistrationService _customerRegistrationService;
		private readonly ICustomerReportService _customerReportService;
		private readonly IDateTimeHelper _dateTimeHelper;
		private readonly ILocalizationService _localizationService;
		private readonly DateTimeSettings _dateTimeSettings;
		private readonly ICountryService _countryService;
		private readonly IStateProvinceService _stateProvinceService;
		private readonly CustomerSettings _customerSettings;
		private readonly IWorkContext _workContext;
		private readonly IStoreContext _storeContext;
		private readonly ICustomerActivityService _customerActivityService;
		private readonly IOrganizationService _organizationService;
		private readonly IDepartmentService _departmentService;
		private readonly IPermissionService _permissionService;
		private readonly IStoreService _storeService;
		private readonly ICacheManager _cacheManager;
		private readonly IExportManager _exportManager;
		private readonly IImportManager _importManager;

		#endregion

		#region Constructors

		public CustomerController(ICustomerService customerService,
			IAuthenticationService authenticationService,
			IEventPublisher eventPublisher,
			IGenericAttributeService genericAttributeService,
			ICustomerRegistrationService customerRegistrationService,
			ICustomerReportService customerReportService,
			IDateTimeHelper dateTimeHelper,
			ILocalizationService localizationService,
			DateTimeSettings dateTimeSettings,
			ICountryService countryService,
			IStateProvinceService stateProvinceService,
			CustomerSettings customerSettings,
			IWorkContext workContext,
			IStoreContext storeContext,
			ICustomerActivityService customerActivityService,
			IOrganizationService organizationService,
			IDepartmentService departmentService,
			IPermissionService permissionService,
			IStoreService storeService,
			ICacheManager cacheManager,
			IExportManager exportManager,
			IImportManager importManager)
		{
			this._customerService = customerService;
			this._authenticationService = authenticationService;
			this._eventPublisher = eventPublisher;
			this._genericAttributeService = genericAttributeService;
			this._customerRegistrationService = customerRegistrationService;
			this._customerReportService = customerReportService;
			this._dateTimeHelper = dateTimeHelper;
			this._localizationService = localizationService;
			this._dateTimeSettings = dateTimeSettings;
			this._countryService = countryService;
			this._stateProvinceService = stateProvinceService;
			this._customerSettings = customerSettings;
			this._workContext = workContext;
			this._storeContext = storeContext;
			this._customerActivityService = customerActivityService;
			this._organizationService = organizationService;
			this._departmentService = departmentService;
			this._permissionService = permissionService;
			this._storeService = storeService;
			this._cacheManager = cacheManager;
			this._exportManager = exportManager;
			this._importManager = importManager;
		}

		#endregion

		#region Utilities

		[NonAction]
		protected virtual string GetCustomerRolesNames(IList<CustomerRole> customerRoles, string separator = ",")
		{
			var sb = new StringBuilder();
			List<string> roles = new List<string> { "Registered", "Guests" };
			customerRoles = customerRoles.Where(m => !roles.Contains(m.SystemName)).ToList();
			for (int i = 0; i < customerRoles.Count; i++)
			{
				sb.Append(customerRoles[i].Name);
				if (i != customerRoles.Count - 1)
				{
					sb.Append(separator);
					sb.Append(" ");
				}
			}
			return sb.ToString();
		}

		[NonAction]
		protected virtual IList<RegisteredCustomerReportLineModel> GetReportRegisteredCustomersModel()
		{
			var report = new List<RegisteredCustomerReportLineModel>();
			report.Add(new RegisteredCustomerReportLineModel
			{
				Period = _localizationService.GetResource("Admin.Customers.Reports.RegisteredCustomers.Fields.Period.7days"),
				Customers = _customerReportService.GetRegisteredCustomersReport(7)
			});

			report.Add(new RegisteredCustomerReportLineModel
			{
				Period = _localizationService.GetResource("Admin.Customers.Reports.RegisteredCustomers.Fields.Period.14days"),
				Customers = _customerReportService.GetRegisteredCustomersReport(14)
			});
			report.Add(new RegisteredCustomerReportLineModel
			{
				Period = _localizationService.GetResource("Admin.Customers.Reports.RegisteredCustomers.Fields.Period.month"),
				Customers = _customerReportService.GetRegisteredCustomersReport(30)
			});
			report.Add(new RegisteredCustomerReportLineModel
			{
				Period = _localizationService.GetResource("Admin.Customers.Reports.RegisteredCustomers.Fields.Period.year"),
				Customers = _customerReportService.GetRegisteredCustomersReport(365)
			});

			return report;
		}


		[NonAction]
		protected virtual CustomerModel PrepareCustomerModelForList(Customer customer)
		{
			return new CustomerModel
			{
				Id = customer.Id,
				Username = customer.IsRegistered() ? customer.Username : "游客",
				FullName = customer.TrueName,
				DepartmentName = customer.DepartmentName,
				TeamName = customer.TeamName,
				CustomerRoleNames = GetCustomerRolesNames(customer.CustomerRoles.ToList()),
				Active = customer.Active,
				CreatedOn = _dateTimeHelper.ConvertToUserTime(customer.CreatedOnUtc, DateTimeKind.Utc),
				LastActivityDate = _dateTimeHelper.ConvertToUserTime(customer.LastActivityDateUtc, DateTimeKind.Utc),
			};
		}

		[NonAction]
		protected virtual string ValidateCustomerRoles(IList<CustomerRole> customerRoles)
		{
			if (customerRoles == null)
				throw new ArgumentNullException("customerRoles");

			bool isInGuestsRole = customerRoles.FirstOrDefault(cr => cr.SystemName == SystemCustomerRoleNames.Guests) != null;
			bool isInRegisteredRole = customerRoles.FirstOrDefault(cr => cr.SystemName == SystemCustomerRoleNames.Registered) != null;
			if ((isInGuestsRole && isInRegisteredRole) || (!isInGuestsRole && !isInRegisteredRole))
				return "角色注册和游客有且只能有一个";

			//no errors
			return "";
		}

		[NonAction]
		protected virtual void PrepareCustomerModel(CustomerModel model, Customer customer, bool excludeProperties)
		{
			var currentCustomer = _workContext.CurrentCustomer;
			if (customer != null)
			{
				model.Id = customer.Id;
				if (!excludeProperties)
				{
					model.Username = customer.Username;
					model.TrueName = customer.TrueName;
					model.DepartmentId = customer.DepartmentId;
					model.DepartmentName = customer.DepartmentName;
					//model.TeamId = customer.TeamId;
					model.TeamName = customer.TeamName;
					model.AdminComment = customer.AdminComment;
					model.Active = customer.Active;
					model.RegisteredInStore = string.Empty;
					model.CreatedOn = _dateTimeHelper.ConvertToUserTime(customer.CreatedOnUtc, DateTimeKind.Utc);
					model.LastActivityDate = _dateTimeHelper.ConvertToUserTime(customer.LastActivityDateUtc, DateTimeKind.Utc);
					model.LastIpAddress = customer.LastIpAddress;
					model.LastVisitedPage = customer.GetAttribute<string>(SystemCustomerAttributeNames.LastVisitedPage);

					if (customer.CustomerRoles != null && customer.CustomerRoles.Any())
					{
						model.SelectedCustomerRoleIds = customer.CustomerRoles.Select(cr => cr.Id).ToList();
					}

					//form fields
					//model.Gender = customer.GetAttribute<string>(SystemCustomerAttributeNames.Gender);
					//model.DateOfBirth = customer.GetAttribute<DateTime?>(SystemCustomerAttributeNames.DateOfBirth);
				}
				if (customer.TeamId > 0)
					model.DepartmentId = customer.TeamId;
			}
			//model.GenderEnabled = _customerSettings.GenderEnabled;
			//model.DateOfBirthEnabled = _customerSettings.DateOfBirthEnabled;
			//customer roles
			var allRoles = _customerService.GetCommonCustomerRoles();
			//var departments = _departmentService.GetAllDepartments(pid: 0);
			//var adminRole = allRoles.FirstOrDefault(c => c.SystemName == SystemCustomerRoleNames.Registered);
			////precheck Registered Role as a default role while creating a new customer through admin
			//if (customer == null && adminRole != null)
			//{
			//	model.SelectedCustomerRoleIds.Add(adminRole.Id);
			//}
			foreach (var role in allRoles)
			{
				if (currentCustomer.IsAdmin() || role.SystemName != SystemCustomerRoleNames.Administrators)
				{
					model.AvailableCustomerRoles.Add(new SelectListItem
					{
						Text = role.Name,
						Value = role.Id.ToString(),
						Selected = model.SelectedCustomerRoleIds.Contains(role.Id)
					});
				}
			}
			//model.AvailableDepartments.Add(new SelectListItem
			//{
			//	Text = "无",
			//	Value = "0"
			//});
			//foreach (var u in departments)
			//{
			//	model.AvailableDepartments.Add(new SelectListItem
			//	{
			//		Text = u.Name,
			//		Value = u.Id.ToString(),
			//		Selected = model.DepartmentId == u.Id
			//	});
			//}
			//model.AvailableTeams.Add(new SelectListItem
			//{
			//	Text = "无",
			//	Value = "0"
			//});
			//if (model.DepartmentId > 0)
			//{
			//	var teams = _departmentService.GetAllDepartments(pid: model.DepartmentId);
			//	foreach (var u in teams)
			//	{
			//		model.AvailableTeams.Add(new SelectListItem
			//		{
			//			Text = u.Name,
			//			Value = u.Id.ToString(),
			//			Selected = model.DepartmentId == u.Id
			//		});
			//	}
			//}

			model.AvailableDepartments.Add(new SelectMenuModel
			{
				name = "请选择",
				id = 0,
				open = true,
			});
			var departments = _departmentService.GetAllDepartments(showHidden: false);
			foreach (var c in departments)
				model.AvailableDepartments.Add(new SelectMenuModel { name = c.Name, id = c.Id, pId = c.PId });

			model.CustomerHours.Year = DateTime.Now.Year;
			model.CustomerHours.AvailableMonths = new List<SelectListItem> {
			new SelectListItem{Value = "0", Text = "每月"},
			new SelectListItem{Value = "1", Text = "一月"},
			new SelectListItem{Value = "2", Text = "二月"},
			new SelectListItem{Value = "3", Text = "三月"},
			new SelectListItem{Value = "4", Text = "四月"},
			new SelectListItem{Value = "5", Text = "五月"},
			new SelectListItem{Value = "6", Text = "六月"},
			new SelectListItem{Value = "7", Text = "七月"},
			new SelectListItem{Value = "8", Text = "八月"},
			new SelectListItem{Value = "9", Text = "九月"},
			new SelectListItem{Value = "10", Text = "十月"},
			new SelectListItem{Value = "11", Text = "十一月"},
			new SelectListItem{Value = "12", Text = "十二月"},
			};
		}

		[NonAction]
		private bool SecondAdminAccountExists(Customer customer)
		{
			var customers = _customerService.GetAllCustomers(customerRoleIds: new[] { _customerService.GetCustomerRoleBySystemName(SystemCustomerRoleNames.Administrators).Id });

			return customers.Any(c => c.Active && c.Id != customer.Id);
		}
		#endregion

		#region Customers

		public virtual ActionResult Index()
		{
			return RedirectToAction("List");
		}

		public virtual ActionResult List()
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageCustomers))
				return AccessDeniedView();

			var customer = _workContext.CurrentCustomer;

			//load registered customers by default
			//var defaultRoleIds = new List<int> { _customerService.GetCustomerRoleBySystemName(SystemCustomerRoleNames.Registered).Id };
			var model = new CustomerListModel
			{
				//SearchCustomerRoleIds = defaultRoleIds,
			};
			model.AvailableCustomerRoles.Add(new SelectListItem
			{
				Text = "全部",
				Value = "0",
			});
			var allRoles = _customerService.GetCommonCustomerRoles();
			foreach (var role in allRoles)
			{
				model.AvailableCustomerRoles.Add(new SelectListItem
				{
					Text = role.Name,
					Value = role.Id.ToString(),
					//Selected = defaultRoleIds.Any(x => x == role.Id)
				});
			}
			model.AvailableDepartments.Add(new SelectMenuModel
			{
				name = "全部",
				id = 0,
				open = true,
			});
			var departments = _departmentService.GetAllDepartments(showHidden: false);
			foreach (var c in departments)
				model.AvailableDepartments.Add(new SelectMenuModel { name = c.Name, id = c.Id, pId = c.PId });

			return View(model);
		}

		[HttpPost]
		public virtual ActionResult CustomerList(DataSourceRequest command, CustomerListModel model)
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageCustomers))
				return AccessDeniedKendoGridJson();

			var customer = _workContext.CurrentCustomer;

			var customers = _customerService.GetAllCustomers(
				customerRoleId: model.SearchCustomerRoleId,
				departId: model.SearchDepartmentId,
				username: model.SearchUsername,
				firstName: model.SearchTruename,
				pageIndex: command.Page - 1,
				pageSize: command.PageSize);
			var gridModel = new DataSourceResult
			{
				Data = customers.Select(PrepareCustomerModelForList),
				Total = customers.TotalCount
			};

			return Json(gridModel);
		}

		public virtual ActionResult Create()
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageCustomers))
				return AccessDeniedView();

			var model = new CustomerModel();
			PrepareCustomerModel(model, null, false);
			//default value
			model.Active = true;
			return View(model);
		}

		[HttpPost, ParameterBasedOnFormName("save-continue", "continueEditing")]
		[FormValueRequired("save", "save-continue")]
		[ValidateInput(false)]
		public virtual ActionResult Create(CustomerModel model, bool continueEditing, FormCollection form)
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageCustomers))
				return AccessDeniedView();

			if (!String.IsNullOrWhiteSpace(model.Username))
			{
				var cust2 = _customerService.GetCustomerByUsername(model.Username);
				if (cust2 != null)
					ModelState.AddModelError("", "用户名已经注册");
			}

			//validate customer roles
			var allCustomerRoles = _customerService.GetAllCustomerRoles(showAll: true);
			var newCustomerRoles = new List<CustomerRole>();
			foreach (var customerRole in allCustomerRoles)
				if (model.SelectedCustomerRoleIds.Contains(customerRole.Id))
					newCustomerRoles.Add(customerRole);

			var adminRole = allCustomerRoles.FirstOrDefault(c => c.SystemName == SystemCustomerRoleNames.Registered);
			if (!newCustomerRoles.Any(m => m.Id == adminRole.Id))
			{
				model.SelectedCustomerRoleIds.Add(adminRole.Id);
				newCustomerRoles.Add(adminRole);
			}

			var customerRolesError = ValidateCustomerRoles(newCustomerRoles);
			if (!String.IsNullOrEmpty(customerRolesError))
			{
				ModelState.AddModelError("", customerRolesError);
				ErrorNotification(customerRolesError, false);
			}
			if (ModelState.IsValid)
			{
				var customer = new Customer
				{
					CustomerGuid = Guid.NewGuid(),
					Username = model.Username,
					TrueName = model.TrueName,
					//DepartmentId = model.DepartmentId,
					//DepartmentName = model.DepartmentName,
					//TeamId = model.TeamId,
					//TeamName = model.TeamName,
					AdminComment = model.AdminComment,
					Active = model.Active,
					CreatedOnUtc = DateTime.UtcNow,
					LastActivityDateUtc = DateTime.UtcNow,
					RegisteredInStoreId = 0
				};
				if (model.DepartmentId > 0)
				{
					var depart = _departmentService.GetDepartmentById(model.DepartmentId);
					if (null != depart)
					{
						if (depart.PId > 0)
						{
							var departParent = _departmentService.GetDepartmentById(depart.PId);
							if (null != departParent)
							{
								customer.DepartmentId = departParent.Id;
								customer.DepartmentName = departParent.Name;
							}
							customer.TeamId = depart.Id;
							customer.TeamName = depart.Name;
						}
						else
						{
							customer.DepartmentId = depart.Id;
							customer.DepartmentName = depart.Name;
							customer.TeamId = 0;
							customer.TeamName = null;
						}
					}
				}
				else
				{
					customer.DepartmentId = 0;
					customer.TeamId = 0;
					customer.DepartmentName = null;
					customer.TeamName = null;
				}
				//model.DepartmentName = _departmentService.GetNameById(model.DepartmentId);
				//if (model.TeamId > 0)
				//	model.TeamName = _departmentService.GetNameById(model.TeamId);
				_customerService.InsertCustomer(customer);

				//form fields
				//if (_customerSettings.GenderEnabled)
				//	_genericAttributeService.SaveAttribute(customer, SystemCustomerAttributeNames.Gender, model.Gender);
				//if (_customerSettings.DateOfBirthEnabled)
				//	_genericAttributeService.SaveAttribute(customer, SystemCustomerAttributeNames.DateOfBirth, model.DateOfBirth);

				//password
				if (!String.IsNullOrWhiteSpace(model.Password))
				{
					var changePassRequest = new ChangePasswordRequest(model.Username, false, _customerSettings.DefaultPasswordFormat, model.Password);
					var changePassResult = _customerRegistrationService.ChangePassword(changePassRequest);
					if (!changePassResult.Success)
					{
						foreach (var changePassError in changePassResult.Errors)
							ErrorNotification(changePassError);
					}
				}

				//customer roles
				foreach (var customerRole in newCustomerRoles)
				{
					//ensure that the current customer cannot add to "Administrators" system role if he's not an admin himself
					if (customerRole.SystemName == SystemCustomerRoleNames.Administrators &&
						!_workContext.CurrentCustomer.IsAdmin())
						continue;

					customer.CustomerRoles.Add(customerRole);
				}
				_customerService.UpdateCustomer(customer);

				//activity log
				_customerActivityService.InsertActivity("AddNewCustomer", "新增用户 Id={0}", customer.Id);

				SuccessNotification("添加成功");
				if (continueEditing)
				{
					//selected tab
					SaveSelectedTabName();

					return RedirectToAction("Edit", new { id = customer.Id });
				}
				return RedirectToAction("List");
			}

			//If we got this far, something failed, redisplay form
			PrepareCustomerModel(model, null, true);
			return View(model);
		}

		public virtual ActionResult Edit(int id)
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageCustomers))
				return AccessDeniedView();

			var customer = _customerService.GetCustomerById(id);
			if (customer == null || customer.Deleted)
				//No customer found with the specified id
				return RedirectToAction("List");

			var model = new CustomerModel();
			PrepareCustomerModel(model, customer, false);
			return View(model);
		}

		[HttpPost, ParameterBasedOnFormName("save-continue", "continueEditing")]
		[FormValueRequired("save", "save-continue")]
		[ValidateInput(false)]
		public virtual ActionResult Edit(CustomerModel model, bool continueEditing, FormCollection form)
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageCustomers))
				return AccessDeniedView();

			var customer = _customerService.GetCustomerById(model.Id);
			if (customer == null || customer.Deleted)
				//No customer found with the specified id
				return RedirectToAction("List");

			//validate customer roles
			var allCustomerRoles = _customerService.GetAllCustomerRoles(showAll: true);
			var newCustomerRoles = new List<CustomerRole>();
			foreach (var customerRole in allCustomerRoles)
				if (model.SelectedCustomerRoleIds.Contains(customerRole.Id))
					newCustomerRoles.Add(customerRole);

			var adminRole = allCustomerRoles.FirstOrDefault(c => c.SystemName == SystemCustomerRoleNames.Registered);
			if (!newCustomerRoles.Any(m => m.Id == adminRole.Id))
			{
				model.SelectedCustomerRoleIds.Add(adminRole.Id);
				newCustomerRoles.Add(adminRole);
			}

			var customerRolesError = ValidateCustomerRoles(newCustomerRoles);
			if (!String.IsNullOrEmpty(customerRolesError))
			{
				ModelState.AddModelError("", customerRolesError);
				ErrorNotification(customerRolesError, false);
			}
			if (ModelState.IsValid)
			{
				try
				{
					customer.AdminComment = model.AdminComment;
					// 编辑用户后作废身份牌
					customer.Token = null;
					customer.TokenIndate = null;
					//prevent deactivation of the last active administrator
					if (!customer.IsAdmin() || model.Active || SecondAdminAccountExists(customer))
						customer.Active = model.Active;
					else
						ErrorNotification(_localizationService.GetResource("Admin.Customers.Customers.AdminAccountShouldExists.Deactivate"));

					//username
					customer.TrueName = model.TrueName;
					//customer.DepartmentId = model.DepartmentId;
					//customer.DepartmentName = _departmentService.GetNameById(model.DepartmentId);
					//customer.TeamId = model.TeamId;
					//customer.TeamName = _departmentService.GetNameById(model.TeamId);

					if (model.DepartmentId > 0)
					{
						var depart = _departmentService.GetDepartmentById(model.DepartmentId);
						if (null != depart)
						{
							if (depart.PId > 0)
							{
								var departParent = _departmentService.GetDepartmentById(depart.PId);
								if (null != departParent)
								{
									customer.DepartmentId = departParent.Id;
									customer.DepartmentName = departParent.Name;
								}
								customer.TeamId = depart.Id;
								customer.TeamName = depart.Name;
							}
							else
							{
								customer.DepartmentId = depart.Id;
								customer.DepartmentName = depart.Name;
								customer.TeamId = 0;
								customer.TeamName = null;
							}
						}
					}
					else
					{
						customer.DepartmentId = 0;
						customer.DepartmentName = null;
						customer.TeamId = 0;
						customer.TeamName = null;
					}
					if (!String.IsNullOrWhiteSpace(model.Username))
					{
						_customerRegistrationService.SetUsername(customer, model.Username);
					}
					else
					{
						customer.Username = model.Username;
					}
					////form fields
					//if (_customerSettings.GenderEnabled)
					//	_genericAttributeService.SaveAttribute(customer, SystemCustomerAttributeNames.Gender, model.Gender);
					//if (_customerSettings.DateOfBirthEnabled)
					//	_genericAttributeService.SaveAttribute(customer, SystemCustomerAttributeNames.DateOfBirth, model.DateOfBirth);

					//customer roles
					foreach (var customerRole in allCustomerRoles)
					{
						//ensure that the current customer cannot add/remove to/from "Administrators" system role
						//if he's not an admin himself
						if (customerRole.SystemName == SystemCustomerRoleNames.Administrators &&
							!_workContext.CurrentCustomer.IsAdmin())
							continue;

						if (model.SelectedCustomerRoleIds.Contains(customerRole.Id))
						{
							//new role
							if (customer.CustomerRoles.Count(cr => cr.Id == customerRole.Id) == 0)
								customer.CustomerRoles.Add(customerRole);
						}
						else
						{
							//prevent attempts to delete the administrator role from the user, if the user is the last active administrator
							if (customerRole.SystemName == SystemCustomerRoleNames.Administrators && !SecondAdminAccountExists(customer))
							{
								ErrorNotification(_localizationService.GetResource("Admin.Customers.Customers.AdminAccountShouldExists.DeleteRole"));
								continue;
							}

							//remove role
							if (customer.CustomerRoles.Count(cr => cr.Id == customerRole.Id) > 0)
								customer.CustomerRoles.Remove(customerRole);
						}
					}
					_customerService.UpdateCustomer(customer);
					//activity log
					_customerActivityService.InsertActivity("EditCustomer", "修改用户 Id={0}", customer.Id);

					SuccessNotification("修改成功");

					if (continueEditing)
					{
						//selected tab
						SaveSelectedTabName();

						return RedirectToAction("Edit", new { id = customer.Id });
					}
					return RedirectToAction("List");
				}
				catch (Exception exc)
				{
					ErrorNotification(exc.Message, false);
				}
			}


			//If we got this far, something failed, redisplay form
			PrepareCustomerModel(model, customer, true);
			return View(model);
		}

		[HttpPost, ActionName("Edit")]
		[FormValueRequired("changepassword")]
		public virtual ActionResult ChangePassword(CustomerModel model)
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageCustomers))
				return AccessDeniedView();

			var customer = _customerService.GetCustomerById(model.Id);
			if (customer == null)
				//No customer found with the specified id
				return RedirectToAction("List");

			//ensure that the current customer cannot change passwords of "Administrators" if he's not an admin himself
			if (customer.IsAdmin() && !_workContext.CurrentCustomer.IsAdmin())
			{
				ErrorNotification("只有管理员能修改密码");
				return RedirectToAction("Edit", new { id = customer.Id });
			}

			if (ModelState.IsValid)
			{
				var changePassRequest = new ChangePasswordRequest(customer.Username, false, _customerSettings.DefaultPasswordFormat, model.Password);
				var changePassResult = _customerRegistrationService.ChangePassword(changePassRequest);
				if (changePassResult.Success)
				{
					if (!string.IsNullOrEmpty(customer.Token))
					{
						// 编辑用户后作废身份牌
						customer.Token = null;
						customer.TokenIndate = null;
						_customerService.UpdateCustomer(customer);
					}
					SuccessNotification("修改密码成功");
					_customerActivityService.InsertActivity("ChangePassword", "修改密码 CustomerId={0}", customer.Id);
				}
				else
					foreach (var error in changePassResult.Errors)
						ErrorNotification(error);
			}

			return RedirectToAction("Edit", new { id = customer.Id });
		}

		[HttpPost]
		public virtual ActionResult Delete(int id)
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageCustomers))
				return AccessDeniedView();

			var customer = _customerService.GetCustomerById(id);
			if (customer == null)
				//No customer found with the specified id
				return RedirectToAction("List");

			try
			{
				//prevent attempts to delete the user, if it is the last active administrator
				if (customer.IsAdmin() && !SecondAdminAccountExists(customer))
				{
					ErrorNotification("不能删除仅有的管理员");
					return RedirectToAction("Edit", new { id = customer.Id });
				}

				//ensure that the current customer cannot delete "Administrators" if he's not an admin himself
				if (customer.IsAdmin() && !_workContext.CurrentCustomer.IsAdmin())
				{
					ErrorNotification("只有管理员能删除");
					return RedirectToAction("Edit", new { id = customer.Id });
				}
				customer.Deleted = true;
				_customerService.UpdateCustomer(customer);

				//activity log
				_customerActivityService.InsertActivity("DeleteCustomer", "删除用户 Id={0}", customer.Id);

				SuccessNotification("删除成功");
				return RedirectToAction("List");
			}
			catch (Exception exc)
			{
				ErrorNotification(exc.Message);
				return RedirectToAction("Edit", new { id = customer.Id });
			}
		}
		#endregion

		#region Customer Hours

		[HttpPost]
		public virtual ActionResult Hours(DataSourceRequest command, int uId)
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageCustomers))
				return AccessDeniedKendoGridJson();

			var hours = _customerService.GetCustomerHours(
				uId,
				pageIndex: command.Page - 1,
				pageSize: command.PageSize);

			var gridModel = new DataSourceResult
			{
				Data = hours.Select(x =>
				{
					return x;
				}),
				Total = hours.Count(),
			};

			return Json(gridModel);
		}

		[ValidateInput(false)]
		public virtual ActionResult HourAdd(int year, int month, int hours, int customerId)
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageCustomers))
				return AccessDeniedView();

			var hour = new CustomerHours
			{
				CustomerId = customerId,
				Year = year,
				Month = month,
				Hours = hours,
			};
			_customerService.InsertCustomerHour(hour);

			return Json(new { Result = true }, JsonRequestBehavior.AllowGet);
		}

		[HttpPost]
		public virtual ActionResult HourUpdate(CustomerModel.CustomerHoursModel model)
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageCustomers))
				return AccessDeniedView();

			var hour = _customerService.GetCustomerHoursById(model.Id);
			if (hour == null)
				return Content("未找到月度工时");

			hour.Year = model.Year;
			hour.Month = model.Month;
			hour.Hours = model.Hours;
			_customerService.UpdateCustomerHour(hour);

			return new NullJsonResult();
		}

		[HttpPost]
		public virtual ActionResult HourDelete(int id)
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageCustomers))
				return AccessDeniedView();

			var hour = _customerService.GetCustomerHoursById(id);
			if (hour == null)
				return Content("未找到月度工时");

			_customerService.DeleteCustomerHour(hour);

			return new NullJsonResult();
		}

		#endregion

		#region Reports

		[ChildActionOnly]
		public virtual ActionResult ReportRegisteredCustomers()
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageCustomers))
				return Content("");

			return PartialView();
		}

		[HttpPost]
		public virtual ActionResult ReportRegisteredCustomersList(DataSourceRequest command)
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageCustomers))
				return AccessDeniedKendoGridJson();

			var model = GetReportRegisteredCustomersModel();
			var gridModel = new DataSourceResult
			{
				Data = model,
				Total = model.Count
			};

			return Json(gridModel);
		}

		[ChildActionOnly]
		public virtual ActionResult CustomerStatistics()
		{

			return PartialView();
		}

		[AcceptVerbs(HttpVerbs.Get)]
		public virtual ActionResult LoadCustomerStatistics(string period)
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageCustomers))
				return Content("");

			var result = new List<object>();

			var nowDt = _dateTimeHelper.ConvertToUserTime(DateTime.Now);
			var timeZone = _dateTimeHelper.CurrentTimeZone;
			var searchCustomerRoleIds = new[] { _customerService.GetCustomerRoleBySystemName(SystemCustomerRoleNames.Registered).Id };

			var culture = new CultureInfo(_workContext.WorkingLanguage.LanguageCulture);

			switch (period)
			{
				case "year":
					//year statistics
					var yearAgoDt = nowDt.AddYears(-1).AddMonths(1);
					var searchYearDateUser = new DateTime(yearAgoDt.Year, yearAgoDt.Month, 1);
					if (!timeZone.IsInvalidTime(searchYearDateUser))
					{
						for (int i = 0; i <= 12; i++)
						{
							result.Add(new
							{
								date = searchYearDateUser.Date.ToString("Y", culture),
								value = _customerService.GetAllCustomers(
									createdFromUtc: _dateTimeHelper.ConvertToUtcTime(searchYearDateUser, timeZone),
									createdToUtc: _dateTimeHelper.ConvertToUtcTime(searchYearDateUser.AddMonths(1), timeZone),
									customerRoleIds: searchCustomerRoleIds,
									pageIndex: 0,
									pageSize: 1).TotalCount.ToString()
							});

							searchYearDateUser = searchYearDateUser.AddMonths(1);
						}
					}
					break;

				case "month":
					//month statistics
					var monthAgoDt = nowDt.AddDays(-30);
					var searchMonthDateUser = new DateTime(monthAgoDt.Year, monthAgoDt.Month, monthAgoDt.Day);
					if (!timeZone.IsInvalidTime(searchMonthDateUser))
					{
						for (int i = 0; i <= 30; i++)
						{
							result.Add(new
							{
								date = searchMonthDateUser.Date.ToString("M", culture),
								value = _customerService.GetAllCustomers(
									createdFromUtc: _dateTimeHelper.ConvertToUtcTime(searchMonthDateUser, timeZone),
									createdToUtc: _dateTimeHelper.ConvertToUtcTime(searchMonthDateUser.AddDays(1), timeZone),
									customerRoleIds: searchCustomerRoleIds,
									pageIndex: 0,
									pageSize: 1).TotalCount.ToString()
							});

							searchMonthDateUser = searchMonthDateUser.AddDays(1);
						}
					}
					break;

				case "week":
				default:
					//week statistics
					var weekAgoDt = nowDt.AddDays(-7);
					var searchWeekDateUser = new DateTime(weekAgoDt.Year, weekAgoDt.Month, weekAgoDt.Day);
					if (!timeZone.IsInvalidTime(searchWeekDateUser))
					{
						for (int i = 0; i <= 7; i++)
						{
							result.Add(new
							{
								date = searchWeekDateUser.Date.ToString("d dddd", culture),
								value = _customerService.GetAllCustomers(
									createdFromUtc: _dateTimeHelper.ConvertToUtcTime(searchWeekDateUser, timeZone),
									createdToUtc: _dateTimeHelper.ConvertToUtcTime(searchWeekDateUser.AddDays(1), timeZone),
									customerRoleIds: searchCustomerRoleIds,
									pageIndex: 0,
									pageSize: 1).TotalCount.ToString()
							});

							searchWeekDateUser = searchWeekDateUser.AddDays(1);
						}
					}
					break;
			}

			return Json(result, JsonRequestBehavior.AllowGet);
		}

		#endregion

		#region Activity log

		[HttpPost]
		public virtual ActionResult ListActivityLog(DataSourceRequest command, int customerId)
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageCustomers) && _workContext.CurrentCustomer.Id != customerId)
				return AccessDeniedKendoGridJson();

			var activityLog = _customerActivityService.GetAllActivities(null, null, customerId, 0, command.Page - 1, command.PageSize);
			var gridModel = new DataSourceResult
			{
				Data = activityLog.Select(x =>
				{
					var m = new CustomerModel.ActivityLogModel
					{
						Id = x.Id,
						ActivityLogTypeName = x.ActivityLogType.Name,
						Comment = x.Comment,
						CreatedOn = _dateTimeHelper.ConvertToUserTime(x.CreatedOnUtc, DateTimeKind.Utc),
						IpAddress = x.IpAddress
					};
					return m;

				}),
				Total = activityLog.TotalCount
			};

			return Json(gridModel);
		}

		#endregion

		#region Export / Import

		[HttpPost, ActionName("List")]
		[FormValueRequired("exportexcel-all")]
		public virtual ActionResult ExportExcelAll(CustomerListModel model)
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageCustomers))
				return AccessDeniedView();

			var customers = _customerService.GetAllCustomers(
				//customerRoleIds: model.SearchCustomerRoleIds.ToArray(),
				customerRoleId: model.SearchCustomerRoleId,
				departId: model.SearchDepartmentId,
				username: model.SearchUsername,
				firstName: model.SearchTruename);

			try
			{
				byte[] bytes = _exportManager.ExportCustomersToXlsx(customers);
				return File(bytes, MimeTypes.TextXlsx, "customers.xlsx");
			}
			catch (Exception exc)
			{
				ErrorNotification(exc);
				return RedirectToAction("List");
			}
		}

		[HttpPost]
		public virtual ActionResult ExportExcelSelected(string selectedIds)
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageCustomers))
				return AccessDeniedView();

			var customers = new List<Customer>();
			if (selectedIds != null)
			{
				var ids = selectedIds
					.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
					.Select(x => Convert.ToInt32(x))
					.ToArray();
				customers.AddRange(_customerService.GetCustomersByIds(ids));
			}

			try
			{
				byte[] bytes = _exportManager.ExportCustomersToXlsx(customers);
				return File(bytes, MimeTypes.TextXlsx, "customers.xlsx");
			}
			catch (Exception exc)
			{
				ErrorNotification(exc);
				return RedirectToAction("List");
			}
		}

		[HttpPost]
		public virtual ActionResult ImportFromXlsx()
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageCustomers))
				return AccessDeniedView();
			int count = 0;
			try
			{
				var file = Request.Files["importexcelfile"];
				if (file != null && file.ContentLength > 0)
				{
					count = _importManager.ImportStatesFromTxt(file.InputStream);
				}
				else
				{
					ErrorNotification(_localizationService.GetResource("Admin.Common.UploadFile"));
					return RedirectToAction("List");
				}
				SuccessNotification("导入成功");
				_customerActivityService.InsertActivity("Import", "成功导入{0}", count);
				return RedirectToAction("List");
			}
			catch (Exception exc)
			{
				ErrorNotification(exc);
				return RedirectToAction("List");
			}
		}
		#endregion

		/// <summary>
		/// 用户列表
		/// </summary>
		/// <param name="departId"></param>
		/// <param name="onlyRepairman">只显示维修人员</param>
		/// <returns></returns>
		/// <exception cref="ArgumentNullException"></exception>
		[AcceptVerbs(HttpVerbs.Get)]
		public virtual ActionResult GetUsersByDepartmentId(string departId, bool onlyRepairman = false)
		{
			// This action method gets called via an ajax request
			if (String.IsNullOrEmpty(departId))
				throw new ArgumentNullException("departId");

			var result = _customerService.GetAllCustomers(
				customerRoleIds: onlyRepairman ? new int[] { _customerService.GetCustomerRoleBySystemName(SystemCustomerRoleNames.Repairman).Id } : null,
				departId: Convert.ToInt32(departId)
				).Select(x => new { id = x.Id, name = x.TrueName ?? x.Username }).ToList();
			//asterisk
			result.Insert(0, new { id = 0, name = "全部" });
			return Json(result, JsonRequestBehavior.AllowGet);
		}

		[AcceptVerbs(HttpVerbs.Get)]
		public virtual ActionResult GetTeamsByDepartmentId(string departmentId)
		{
			// This action method gets called via an ajax request
			if (String.IsNullOrEmpty(departmentId))
				throw new ArgumentNullException("departmentId");

			var result = _departmentService.GetAllDepartments(pid: Convert.ToInt32(departmentId),
				pageSize: int.MaxValue).Select(x => new { id = x.Id, name = x.Name }).ToList();
			//asterisk
			result.Insert(0, new { id = 0, name = "无" });
			return Json(result, JsonRequestBehavior.AllowGet);
		}
	}
}
